:- module(suspend).
:- export portray_delay_reified / 2.
:- export portray_delayed_goals / 2.
:- export neg_body / 3.
:- export '=>_body' / 4.
:- export or_body / 4.
:- export and_body / 4.
:- export '>_body' / 4.
:- export '<_body' / 4.
:- export '>=_body' / 4.
:- export '=<_body' / 4.
:- export '=\\=_body' / 4.
:- export '=:=_body' / 4.
:- export '$>_body' / 4.
:- export '$<_body' / 4.
:- export '$>=_body' / 4.
:- export '$=<_body' / 4.
:- export '$\\=_body' / 4.
:- export '$=_body' / 4.
:- export '#>_body' / 4.
:- export '#<_body' / 4.
:- export '#>=_body' / 4.
:- export '#=<_body' / 4.
:- export '#\\=_body' / 4.
:- export '#=_body' / 4.
:- export '#::_body' / 4.
:- export '$::_body' / 4.
:- export '::_body' / 4.
:- export neg / 2.
:- export => / 3.
:- export or / 3.
:- export and / 3.
:- export (#>) / 3.
:- export (#<) / 3.
:- export (#=<) / 3.
:- export (#>=) / 3.
:- export (#\=) / 3.
:- export (#=) / 3.
:- export $=< / 3.
:- export $>= / 3.
:- export $< / 3.
:- export $> / 3.
:- export $\= / 3.
:- export $= / 3.
:- export (=<) / 3.
:- export (>=) / 3.
:- export (<) / 3.
:- export (>) / 3.
:- export (=\=) / 3.
:- export (=:=) / 3.
:- export #:: / 3.
:- export $:: / 3.
:- export (::) / 3.
:- export neg_body / 2.
:- export '=>_body' / 3.
:- export or_body / 3.
:- export and_body / 3.
:- export '>_body' / 3.
:- export '<_body' / 3.
:- export '>=_body' / 3.
:- export '=<_body' / 3.
:- export '=\\=_body' / 3.
:- export '=:=_body' / 3.
:- export '$>_body' / 3.
:- export '$<_body' / 3.
:- export '$>=_body' / 3.
:- export '$=<_body' / 3.
:- export '$\\=_body' / 3.
:- export '$=_body' / 3.
:- export '#>_body' / 3.
:- export '#<_body' / 3.
:- export '#>=_body' / 3.
:- export '#=<_body' / 3.
:- export '#\\=_body' / 3.
:- export '#=_body' / 3.
:- export '#::_body' / 3.
:- export '$::_body' / 3.
:- export '::_body' / 3.
:- export neg / 1.
:- export => / 2.
:- export or / 2.
:- export and / 2.
:- export (#<) / 2.
:- export (#>) / 2.
:- export (#=<) / 2.
:- export (#>=) / 2.
:- export (#\=) / 2.
:- export (#=) / 2.
:- export $< / 2.
:- export $> / 2.
:- export $=< / 2.
:- export $>= / 2.
:- export $\= / 2.
:- export $= / 2.
:- export (<) / 2.
:- export (>) / 2.
:- export (=<) / 2.
:- export (>=) / 2.
:- export (=\=) / 2.
:- export (=:=) / 2.
:- export reals / 1.
:- export integers / 1.
:- export #:: / 2.
:- export $:: / 2.
:- export (::) / 2.
:- export tr_if_suspend / 3.
:- export delayed_goals_number_suspend / 2.
:- export suspensions_suspend / 3.
:- export compare_instances_suspend / 3.
:- export unify_suspend / 2.
:- import :@ / 3, eval / 3, get_flag_body / 4, insert_suspension / 4, setarg / 3, suspensions_to_goals / 3 from sepia_kernel.
:- global meta_attribute(suspend, [unify : unify_suspend / 2, compare_instances : compare_instances_suspend / 3, suspensions : suspensions_suspend / 3, delayed_goals_number : delayed_goals_number_suspend / 2]).
:- export macro((if) / 2, suspend : tr_if_suspend / 3, [clause]).
:- export op(750, fx, [neg]).
:- export op(760, yfx, [and]).
:- export op(770, yfx, [or]).
:- export op(780, yfx, [=>]).
:- export op(700, xfx, [#::, $::, $=, $\=, $>=, $=<, $>, $<]).
:- export portray(delay_until_ground / 3, suspend : portray_delayed_goals / 2, [goal]).
:- export portray(delay_reified / 4, suspend : portray_delay_reified / 2, [goal]).
:- comment(summary, "Lazy-checking versions of arithmetic primitives, and the suspend-attribute").
:- comment(date, "$Date: 2004/11/19 14:54:49 $").
:- comment(copyright, "Imperial College London and ICL").
:- comment(author, "Micha Meier, ECRC, Joachim Schimpf, ECRC and IC-Parc").
:- comment(desc, html("    This library provides the following:\n<UL>\n    <LI>the <B>suspend</B> pseudo-solver for general arithmetic\n    <LI>the <B>suspend</B> attribute\n</UL>\n    The suspend pseudo-solver for arithmetic comparisons simply consists\n    of suspending (lazy-checking) versions of all arithmetic comparisons\n    (&gt;/2, #&gt;/2, etc).  These all suspend until all their variables\n    have been instantiated, then they wake up and test the condition,\n    succeeding or failing as appropriate. Together with a search routine,\n    this provides the means to implement simple test-and-generate algorithms.\n<P>\n    The suspend-attribute is a basis for the implementation of similar\n    user-defined data-driven computations that react to variable instantiation,\n    variable binding, or general variable-constraining events.  The suspend-\n    attribute defines the following three suspension lists (and thus waking\n    conditions) for a variable:\n<DL>\n    <DT><STRONG>inst</STRONG><DD>\n    \twoken when variable is instantiated.\n    <DT><STRONG>bound</STRONG><DD>\n    \twoken when variable is bound, even to an other variable.\n    <DT><STRONG>constrained</STRONG><DD>\n    \twoken when variable is (further) constrained.  This is\n\ttriggered by the notify_constrained built-in.\n</DL>\n    These three lists can be used as waking conditions in the suspend/3,4\n    built-in. Variables using the suspend-attribute do not have to be\n    declared specially, the attribute is implicitly created when needed.\n    ")).
:- comment(#:: / 2, [summary : "Range constraint combined with integrality constraint", template : "?Vars #:: ?Range", see_also : [$:: / 2, (::) / 2, #:: / 3, integers / 1, reals / 1], args : ["Vars" : "Variable or integer, or a list of variables or integers", "Range" : "Variable or Lo..Hi, where Lo and Hi are variables or integer expressions"], exceptions : [5 : "Range contains non-integers."], fail_if : "Vars contains non-integers or integers that do not fall within Range.", eg : "\n    ?- X #:: 1 .. 5, X = 3.\n    X = 3\n    Yes (0.00s cpu)\n\n    ?- X #:: 1 .. 5, X = 6.\n    No (0.00s cpu)\n\n    ?- X #:: 1 .. 5, X = 3.0.\n    No (0.00s cpu)\n    ", desc : html("   This constraint suspends until its arguments are ground. It then succeeds\n   iff all the elements of the list Vars are integers within the range\n   specified by Range.\n<P>\n   The range must eventually be in the form Lo..Hi, where Lo and Hi are \n   expressions evaluating to integers.")]).
:- comment(#:: / 3, [summary : "Reified range constraint combined with integrality constraint", args : ["Vars" : "Variable or integer, or a list of variables or integers", "Range" : "Variable or Lo..Hi, where Lo and Hi are variables or integer expressions", "Bool" : "Variable, 0 or 1"], see_also : [#:: / 2], exceptions : [5 : "Range contains non-integers."], eg : "\n    ?- #::(X, 1 .. 5, B), X = 3.\n    B = 1\n    X = 3\n    Yes (0.00s cpu)\n\n    % range violated\n    ?- #::(X, 1 .. 5, B), X = 6.\n    B = 0\n    X = 6\n    Yes (0.00s cpu)\n\n    % integrality violated\n    ?- #::(X, 1 .. 5, B), X = 3.0.\n    B = 0\n    X = 3.0\n    Yes (0.00s cpu)\n    ", desc : html("    Reified version of #::/2, i.e. the truth value of the range constraint is\n    reflected in the value of the 0/1 variable Bool.\n<P>\n    This constraint suspends until its first two arguments are ground.\n    It then unifies Bool according to the truth value of the corresponding\n    #::/2 constraint.\n<P>\n    Note: as opposed to #::/2, the first argument cannot be a list.\n    ")]).
:- comment((#<) / 2, [summary : "The integer value of Expr1 is less than the integer value of Expr2.", template : "?Expr1 #< ?Expr2", see_also : [(#<) / 3, _36657 : (#<) / 2], args : ["Expr1" : "An integer arithmetic expression", "Expr2" : "An integer arithmetic expression"], fail_if : "   fails if the value of Expr1 is not less than the value of Expr2, or if either do not evaluate to an integer.", exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("   Suspends until both Expr1 and Expr2 are ground, and then both arguments\n   are evaluated and compared, succeeding iff they are both integers and \n   Expr1 is less than Expr2.\n")]).
:- comment((#<) / 3, [summary : "Reified arithmetic comparison", see_also : [(#<) / 2], args : ["Expr1" : "An arithmetic expression", "Expr2" : "An arithmetic expression", "Bool" : "Variable, 0 or 1"], exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("    Reified version of #</2, i.e. the truth value of the comparison is\n    reflected in the value of the 0/1 variable Bool.\n<P>\n    This constraint suspends until its first two arguments are ground.\n    It then unifies Bool according to the truth value of the corresponding\n    #</2 constraint.\n")]).
:- comment((#=) / 2, [summary : "The integer value of Expr1 is equal to the integer value of Expr2.", template : "?Expr1 #= ?Expr2", see_also : [(#=) / 3, _34579 : (#=) / 2], args : ["Expr1" : "An integer arithmetic expression", "Expr2" : "An integer arithmetic expression"], fail_if : "   fails if the value of Expr1 is not equal to the value of Expr2, or if either do not evaluate to an integer.", exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("   Suspends until both Expr1 and Expr2 are ground, and then both arguments\n   are evaluated and compared, succeeding iff they are both integers and are\n   equal.\n")]).
:- comment((#=) / 3, [summary : "Reified arithmetic comparison", see_also : [(#=) / 2], args : ["Expr1" : "An arithmetic expression", "Expr2" : "An arithmetic expression", "Bool" : "Variable, 0 or 1"], exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("    Reified version of #=/2, i.e. the truth value of the comparison is\n    reflected in the value of the 0/1 variable Bool.\n<P>\n    This constraint suspends until its first two arguments are ground.\n    It then unifies Bool according to the truth value of the corresponding\n    #=/2 constraint.\n")]).
:- comment((#=<) / 2, [summary : "The integer value of Expr1 is less than or equal to the integer value of Expr2.", template : "?Expr1 #=< ?Expr2", see_also : [(#=<) / 3, _35825 : (#=<) / 2], args : ["Expr1" : "An integer arithmetic expression", "Expr2" : "An integer arithmetic expression"], fail_if : "   fails if the value of Expr1 is greater than the value of Expr2, or if either do not evaluate to an integer.", exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("   Suspends until both Expr1 and Expr2 are ground, and then both arguments\n   are evaluated and compared, succeeding iff they are both integers and \n   Expr1 is less than or equal to Expr2.\n")]).
:- comment((#=<) / 3, [summary : "Reified arithmetic comparison", see_also : [(#=<) / 2], args : ["Expr1" : "An arithmetic expression", "Expr2" : "An arithmetic expression", "Bool" : "Variable, 0 or 1"], exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("    Reified version of #=</2, i.e. the truth value of the comparison is\n    reflected in the value of the 0/1 variable Bool.\n<P>\n    This constraint suspends until its first two arguments are ground.\n    It then unifies Bool according to the truth value of the corresponding\n    #=</2 constraint.\n")]).
:- comment((#>) / 2, [summary : "The integer value of Expr1 is greater than the integer value of Expr2.", template : "?Expr1 #> ?Expr2", see_also : [(#>) / 3, _36241 : (#>) / 2], args : ["Expr1" : "An integer arithmetic expression", "Expr2" : "An integer arithmetic expression"], fail_if : "   fails if the value of Expr1 is not greater than the value of Expr2, or if either do not evaluate to an integer.", exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("   Suspends until both Expr1 and Expr2 are ground, and then both arguments\n   are evaluated and compared, succeeding iff they are both integers and \n   Expr1 is greater than Expr2.\n")]).
:- comment((#>) / 3, [summary : "Reified arithmetic comparison", see_also : [(#>) / 2], args : ["Expr1" : "An arithmetic expression", "Expr2" : "An arithmetic expression", "Bool" : "Variable, 0 or 1"], exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("    Reified version of #>/2, i.e. the truth value of the comparison is\n    reflected in the value of the 0/1 variable Bool.\n<P>\n    This constraint suspends until its first two arguments are ground.\n    It then unifies Bool according to the truth value of the corresponding\n    #>/2 constraint.\n")]).
:- comment((#>=) / 2, [summary : "The integer value of Expr1 is greater than or equal to the integer value of Expr2.", template : "?Expr1 #>= ?Expr2", see_also : [(#>=) / 3, _35407 : (#>=) / 2], args : ["Expr1" : "An integer arithmetic expression", "Expr2" : "An integer arithmetic expression"], fail_if : "   fails if the value of Expr1 is less than the value of Expr2, or if either do not evaluate to an integer.", exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("   Suspends until both Expr1 and Expr2 are ground, and then both arguments\n   are evaluated and compared, succeeding iff they are both integers and \n   Expr1 is greater than or equal to Expr2.\n")]).
:- comment((#>=) / 3, [summary : "Reified arithmetic comparison", see_also : [(#>=) / 2], args : ["Expr1" : "An arithmetic expression", "Expr2" : "An arithmetic expression", "Bool" : "Variable, 0 or 1"], exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("    Reified version of #>=/2, i.e. the truth value of the comparison is\n    reflected in the value of the 0/1 variable Bool.\n<P>\n    This constraint suspends until its first two arguments are ground.\n    It then unifies Bool according to the truth value of the corresponding\n    #>=/2 constraint.\n")]).
:- comment((#\=) / 2, [summary : "The integer value of Expr1 is not equal to the integer value of Expr2.", template : "?Expr1 #\\= ?Expr2", see_also : [(#\=) / 3, _34992 : (#\=) / 2], args : ["Expr1" : "An integer arithmetic expression", "Expr2" : "An integer arithmetic expression"], fail_if : "   fails if the value of Expr1 is equal to the value of Expr2, or if either do not evaluate to an integer.", exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("   Suspends until both Expr1 and Expr2 are ground, and then both arguments\n   are evaluated and compared, succeeding iff they are both integers and are\n   not equal.\n")]).
:- comment((#\=) / 3, [summary : "Reified arithmetic comparison", see_also : [(#\=) / 2], args : ["Expr1" : "An arithmetic expression", "Expr2" : "An arithmetic expression", "Bool" : "Variable, 0 or 1"], exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("    Reified version of #\\=/2, i.e. the truth value of the comparison is\n    reflected in the value of the 0/1 variable Bool.\n<P>\n    This constraint suspends until its first two arguments are ground.\n    It then unifies Bool according to the truth value of the corresponding\n    #\\=/2 constraint.\n")]).
:- comment($:: / 2, [summary : "Pure range constraint", template : "?Vars #:: ?Range", args : ["Vars" : "Variable or number, or a list of variables or numbers", "Range" : "Variable or Lo..Hi, where Lo and Hi are variables or numeric expressions"], see_also : [(::) / 2, #:: / 2, $:: / 3, integers / 1, reals / 1], fail_if : "Vars contains numbers that do not fall within Range.", eg : "\n    ?- X $:: 1 .. 5, X = 3.0.\n    X = 3.0\n    Yes (0.00s cpu)\n\n    ?- X $:: 1 .. 5, X = 3.\n    X = 3\n    Yes (0.00s cpu)\n\n    ?- X $:: 1.0 .. 5.0, X = 3.\n    X = 3\n    Yes (0.00s cpu)\n\n    ?- X $:: 1.0 .. 5.0, X = 3.0.\n    X = 3.0\n    Yes (0.00s cpu)\n    ", desc : html("   This constraint suspends until its arguments are ground. It then succeeds\n   iff all the elements of the list Vars are numbers within the range\n   specified by Range.\n<P>\n   The range must eventually be in the form Lo..Hi, where Lo and Hi are \n   expressions evaluating to numbers. The type of these numbers is irrelevant.")]).
:- comment($:: / 3, [summary : "Reified pure range constraint", args : ["Vars" : "Variable or number, or a list of variables or numbers", "Range" : "Variable or Lo..Hi, where Lo and Hi are variables or numeric expressions", "Bool" : "Variable, 0 or 1"], see_also : [$:: / 2], eg : "\n    ?- $::(X, 1 .. 5, B), X = 3.0.\n    B = 1\n    X = 3.0\n    Yes (0.00s cpu)\n\n    % range violated\n    ?- $::(X, 1 .. 5, B), X = 6.\n    B = 0\n    X = 6\n    Yes (0.00s cpu)\n    ", desc : html("    Reified version of $::/2, i.e. the truth value of the range constraint is\n    reflected in the value of the 0/1 variable Bool.\n<P>\n    This constraint suspends until its first two arguments are ground.\n    It then unifies Bool according to the truth value of the corresponding\n    $::/2 constraint.\n<P>\n    Note: as opposed to $::/2, the first argument cannot be a list.\n    ")]).
:- comment($< / 2, [summary : "The value of Expr1 is less than the value of Expr2.", template : "?Expr1 $< ?Expr2", see_also : [$< / 3, suspend : (<) / 2, _34143 : $< / 2], args : ["Expr1" : "An arithmetic expression", "Expr2" : "An arithmetic expression"], fail_if : "   fails if the value of Expr1 is not less than the value of Expr2", exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("   Suspends until both Expr1 and Expr2 are ground, and then both arguments\n   are evaluated and compared, succeeding iff Expr1 is less than Expr2\n   (beware of rounding errors when comparing reals).\n")]).
:- comment($< / 3, [summary : "Reified arithmetic comparison", see_also : [$< / 2, (<) / 3], args : ["Expr1" : "An arithmetic expression", "Expr2" : "An arithmetic expression", "Bool" : "Variable, 0 or 1"], exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("    Reified version of $</2, i.e. the truth value of the comparison is\n    reflected in the value of the 0/1 variable Bool.\n<P>\n    This constraint suspends until its first two arguments are ground.\n    It then unifies Bool according to the truth value of the corresponding\n    $</2 constraint.\n")]).
:- comment($= / 2, [summary : "The value of Expr1 is equal to the value of Expr2.", template : "?Expr1 $= ?Expr2", see_also : [$= / 3, suspend : (=:=) / 2, _31927 : $= / 2], args : ["Expr1" : "An arithmetic expression", "Expr2" : "An arithmetic expression"], fail_if : "   fails if the value of Expr1 is not equal to the value of Expr2", exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("   Suspends until both Expr1 and Expr2 are ground, and then both arguments\n   are evaluated and compared, succeeding iff they are equal (beware of \n   rounding errors when comparing reals).\n")]).
:- comment($= / 3, [summary : "Reified arithmetic comparison", see_also : [$= / 2, (=:=) / 3], args : ["Expr1" : "An arithmetic expression", "Expr2" : "An arithmetic expression", "Bool" : "Variable, 0 or 1"], exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("    Reified version of $=/2, i.e. the truth value of the comparison is\n    reflected in the value of the 0/1 variable Bool.\n<P>\n    This constraint suspends until its first two arguments are ground.\n    It then unifies Bool according to the truth value of the corresponding\n    $=/2 constraint.\n")]).
:- comment($=< / 2, [summary : "The value of Expr1 is less than or equal to the value of Expr2.", template : "?Expr1 $=< ?Expr2", see_also : [$=< / 3, suspend : (=<) / 2, _33256 : $=< / 2], args : ["Expr1" : "An arithmetic expression", "Expr2" : "An arithmetic expression"], fail_if : "   fails if the value of Expr1 is greater than the value of Expr2", exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("   Suspends until both Expr1 and Expr2 are ground, and then both arguments\n   are evaluated and compared, succeeding iff Expr1 is less than or equal to\n   Expr2 (beware of rounding errors when comparing reals).\n")]).
:- comment($=< / 3, [summary : "Reified arithmetic comparison", see_also : [$=< / 2, (=<) / 3], args : ["Expr1" : "An arithmetic expression", "Expr2" : "An arithmetic expression", "Bool" : "Variable, 0 or 1"], exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("    Reified version of $=</2, i.e. the truth value of the comparison is\n    reflected in the value of the 0/1 variable Bool.\n<P>\n    This constraint suspends until its first two arguments are ground.\n    It then unifies Bool according to the truth value of the corresponding\n    $=</2 constraint.\n")]).
:- comment($> / 2, [summary : "The value of Expr1 is greater than the value of Expr2.", template : "?Expr1 $> ?Expr2", see_also : [$> / 3, suspend : (>) / 2, _33700 : $> / 2], args : ["Expr1" : "An arithmetic expression", "Expr2" : "An arithmetic expression"], fail_if : "   fails if the value of Expr1 is not greater than the value of Expr2", exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("   Suspends until both Expr1 and Expr2 are ground, and then both arguments\n   are evaluated and compared, succeeding iff Expr1 is greater than Expr2 \n   (beware of rounding errors when comparing reals).\n")]).
:- comment($> / 3, [summary : "Reified arithmetic comparison", see_also : [$> / 2, (>) / 3], args : ["Expr1" : "An arithmetic expression", "Expr2" : "An arithmetic expression", "Bool" : "Variable, 0 or 1"], exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("    Reified version of $>/2, i.e. the truth value of the comparison is\n    reflected in the value of the 0/1 variable Bool.\n<P>\n    This constraint suspends until its first two arguments are ground.\n    It then unifies Bool according to the truth value of the corresponding\n    $>/2 constraint.\n")]).
:- comment($>= / 2, [summary : "The value of Expr1 is greater than or equal to the value of Expr2.", template : "?Expr1 $>= ?Expr2", see_also : [$>= / 3, suspend : (>=) / 2, _32811 : $>= / 2], args : ["Expr1" : "An arithmetic expression", "Expr2" : "An arithmetic expression"], fail_if : "   fails if the value of Expr1 is smaller than the value of Expr2", exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("   Suspends until both Expr1 and Expr2 are ground, and then both arguments\n   are evaluated and compared, succeeding iff Expr1 is than greater or equal\n   to Expr2 (beware of rounding errors when comparing reals).\n")]).
:- comment($>= / 3, [summary : "Reified arithmetic comparison", see_also : [$>= / 2, (>=) / 3], args : ["Expr1" : "An arithmetic expression", "Expr2" : "An arithmetic expression", "Bool" : "Variable, 0 or 1"], exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("    Reified version of $>=/2, i.e. the truth value of the comparison is\n    reflected in the value of the 0/1 variable Bool.\n<P>\n    This constraint suspends until its first two arguments are ground.\n    It then unifies Bool according to the truth value of the corresponding\n    $>=/2 constraint.\n")]).
:- comment($\= / 2, [summary : "The value of Expr1 is not equal to the value of Expr2.", template : "?Expr1 $\\= ?Expr2", see_also : [$\= / 3, suspend : (=\=) / 2, _32368 : $\= / 2], args : ["Expr1" : "An arithmetic expression", "Expr2" : "An arithmetic expression"], fail_if : "   fails if the value of Expr1 is equal to the value of Expr2", exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("   Suspends until both Expr1 and Expr2 are ground, and then both arguments\n   are evaluated and compared, succeeding iff they are not equal (beware of \n   rounding errors when comparing reals).\n")]).
:- comment($\= / 3, [summary : "Reified arithmetic comparison", see_also : [$\= / 2, (=\=) / 3], args : ["Expr1" : "An arithmetic expression", "Expr2" : "An arithmetic expression", "Bool" : "Variable, 0 or 1"], exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("    Reified version of $\\=/2, i.e. the truth value of the comparison is\n    reflected in the value of the 0/1 variable Bool.\n<P>\n    This constraint suspends until its first two arguments are ground.\n    It then unifies Bool according to the truth value of the corresponding\n    $\\=/2 constraint.\n")]).
:- comment((::) / 2, [summary : "Range constraint with optional integrality constraint", template : "?Vars :: ?Range", args : ["Vars" : "Variable or number, or a list of variables or numbers", "Range" : "Variable or Lo..Hi, where Lo and Hi are variables or numeric expressions"], see_also : [$:: / 2, #:: / 2, (::) / 3, integers / 1, reals / 1], fail_if : "Vars contains numbers that do not fall within Range, or violate the optional integrality constraint.", eg : "\n    % with integrality constraint\n    ?- X :: 1 .. 5, X = 3.\n    X = 3\n    Yes (0.00s cpu)\n\n    ?- X :: 1 .. 5, X = 6.\n    No (0.00s cpu)\n\n    ?- X :: 1 .. 5, X = 3.0.\n    No (0.00s cpu)\n\n    % without integrality constraint\n    ?- X :: 1.0 .. 5.0, X = 3.\n    X = 3\n    Yes (0.00s cpu)\n\n    ?- X :: 1.0 .. 5.0, X = 3.0.\n    X = 3.0\n    Yes (0.00s cpu)\n    ", desc : html("   This constraint suspends until its arguments are ground. It then succeeds\n   iff all the elements of the list Vars are numbers within the range\n   specified by Range.\n<P>\n   The range must eventually be in the form Lo..Hi, where Lo and Hi are \n   expressions evaluating to numbers. If both are integers, then Vars must\n   also be integers (integer or list of integers).")]).
:- comment((::) / 3, [summary : "Reified range constraint with optional integrality constraint", args : ["Var" : "Variable or number", "Range" : "Variable or Lo..Hi, where Lo and Hi are variables or numeric expressions", "Bool" : "Variable, 0 or 1"], see_also : [(::) / 2], eg : "\n    ?- ::(X, 1 .. 5, B), X = 3.\n    B = 1\n    X = 3\n    Yes (0.00s cpu)\n\n    ?- ::(X, 1.0 .. 5.0, B), X = 3.0.\n    B = 1\n    X = 3.0\n    Yes (0.00s cpu)\n\n    % range violated\n    ?- ::(X, 1 .. 5, B), X = 6.\n    B = 0\n    X = 6\n    Yes (0.00s cpu)\n\n    % integrality violated\n    ?- ::(X, 1 .. 5, B), X = 3.0.\n    B = 0\n    X = 3.0\n    Yes (0.00s cpu)\n    ", desc : html("    Reified version of ::/2, i.e. the truth value of the range constraint is\n    reflected in the value of the 0/1 variable Bool.\n<P>\n    This constraint suspends until its first two arguments are ground.\n    It then unifies Bool according to the truth value of the corresponding\n    ::/2 constraint.\n<P>\n    Note: as opposed to ::/2, the first argument cannot be a list.\n    ")]).
:- comment((<) / 2, [summary : "The value of Expr1 is less than the value of Expr2.", template : "?Expr1 < ?Expr2", see_also : [(<) / 3, _31511 : (<) / 2], args : ["Expr1" : "An arithmetic expression", "Expr2" : "An arithmetic expression"], fail_if : "   fails if the value of Expr1 is not less than the value of Expr2", exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("   Suspends until both Expr1 and Expr2 are ground, and then both arguments\n   are evaluated and compared, succeeding iff Expr1 is less than Expr2\n   (beware of rounding errors when comparing reals).\n")]).
:- comment((<) / 3, [summary : "Reified arithmetic comparison", see_also : [(<) / 2, $< / 3], args : ["Expr1" : "An arithmetic expression", "Expr2" : "An arithmetic expression", "Bool" : "Variable, 0 or 1"], exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("    Reified version of </2, i.e. the truth value of the comparison is\n    reflected in the value of the 0/1 variable Bool.\n<P>\n    This constraint suspends until its first two arguments are ground.\n    It then unifies Bool according to the truth value of the corresponding\n    </2 constraint.\n")]).
:- comment((=:=) / 2, [summary : "The value of Expr1 is equal to the value of Expr2.", template : "?Expr1 =:= ?Expr2", see_also : [(=:=) / 3, _29467 : (=:=) / 2], args : ["Expr1" : "An arithmetic expression", "Expr2" : "An arithmetic expression"], fail_if : "   fails if the value of Expr1 is not equal to the value of Expr2", exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("   Suspends until both Expr1 and Expr2 are ground, and then both arguments\n   are evaluated and compared, succeeding iff they are equal (beware of \n   rounding errors when comparing reals).\n")]).
:- comment((=:=) / 3, [summary : "Reified arithmetic comparison", see_also : [(=:=) / 2, $= / 3], args : ["Expr1" : "An arithmetic expression", "Expr2" : "An arithmetic expression", "Bool" : "Variable, 0 or 1"], exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("    Reified version of =:=/2, i.e. the truth value of the comparison is\n    reflected in the value of the 0/1 variable Bool.\n<P>\n    This constraint suspends until its first two arguments are ground.\n    It then unifies Bool according to the truth value of the corresponding\n    =:=/2 constraint.\n")]).
:- comment((=<) / 2, [summary : "The value of Expr1 is less than or equal to the value of Expr2.", template : "?Expr1 =< ?Expr2", see_also : [(=<) / 3, _30694 : (=<) / 2], args : ["Expr1" : "An arithmetic expression", "Expr2" : "An arithmetic expression"], fail_if : "   fails if the value of Expr1 is greater than the value of Expr2", exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("   Suspends until both Expr1 and Expr2 are ground, and then both arguments\n   are evaluated and compared, succeeding iff Expr1 is less than or equal to\n   Expr2 (beware of rounding errors when comparing reals).\n")]).
:- comment((=<) / 3, [summary : "Reified arithmetic comparison", see_also : [(=<) / 2, $=< / 3], args : ["Expr1" : "An arithmetic expression", "Expr2" : "An arithmetic expression", "Bool" : "Variable, 0 or 1"], exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("    Reified version of =</2, i.e. the truth value of the comparison is\n    reflected in the value of the 0/1 variable Bool.\n<P>\n    This constraint suspends until its first two arguments are ground.\n    It then unifies Bool according to the truth value of the corresponding\n    =</2 constraint.\n")]).
:- comment(=> / 2, [summary : "If Expr1 arithmetically evaluates to 1, so does Expr2 (implication)", template : "?Expr1 => ?Expr2", see_also : [=> / 3, and / 2, or / 2, neg / 1, _44827 : => / 2], args : ["Expr1" : "A boolean expression", "Expr2" : "A boolean expression"], fail_if : "Expr1 evaluates to 1 and Expr2 evaluates to 0", eg : "\n\t?- 0 => B, B = 0.\n\tB = 0\n\tYes (0.00s cpu)\n\n\t?- 0 => B, B = 1.\n\tB = 1\n\tYes (0.00s cpu)\n\n\t?- 1 => B, B = 0.\n\tNo (0.00s cpu)\n\n\t?- 1 => B, B = 1.\n\tB = 1\n\tYes (0.00s cpu)\n\n\t% arguments are typically reifiable expressions:\n\t?- X > Y => X > Y+10, X = 5, Y = 3.\n\tNo (0.00s cpu)\n\n\t% the previous example is equivalent to:\n\t?- >(X,Y,B1), >(X,Y+10,B2), B1 => B2, X = 5, Y = 3.\n\tNo (0.00s cpu)\n\n\t% and/or/=>/neg are themselves reifiable:\n\t?- neg(A => B) or (C => D), A=1, B=0, C=0, D=1.\n\tA = 1\n\tB = 0\n\tC = 0\n\tD = 1\n\tYes (0.00s cpu)\n\t", exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("    Suspends until both Expr1 and Expr2 are ground, and then both arguments\n    are evaluated. Succeeds if the truth of Expr1 implies Expr2, i.e. if Expr1\n    evaluates to 1, Expr2 must evaluate to 1, otherwise Expr2 can evaluate to\n    1 or 0. Logically equivalent to\n    <PRE>\n    \tneg(Expr1) or Expr2.\n    </PRE>\n    Typically, the expressions contains reifiable constraints, in which case\n    a corresponding reified constraint is set up, and the expression is\n    replaced by the resulting boolean variable.\n")]).
:- comment(=> / 3, [summary : "Reified boolean operation", see_also : [=> / 2], args : ["Expr1" : "An arithmetic expression", "Expr2" : "An arithmetic expression", "Bool" : "Variable, 0 or 1"], exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("    Reified version of =>/2, i.e. the truth value of the boolean operation\n    is reflected in the value of the 0/1 variable Bool.\n<P>\n    This constraint suspends until its first two arguments are ground.\n    It then unifies Bool according to the truth value of the corresponding\n    =>/2 constraint.\n")]).
:- comment((=\=) / 2, [summary : "The value of Expr1 is not equal to the value of Expr2.", template : "?Expr1 =\\= ?Expr2", see_also : [(=\=) / 3, _29874 : (=\=) / 2], args : ["Expr1" : "An arithmetic expression", "Expr2" : "An arithmetic expression"], fail_if : "   fails if the value of Expr1 is equal to the value of Expr2", exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("   Suspends until both Expr1 and Expr2 are ground, and then both arguments\n   are evaluated and compared, succeeding iff they are not equal (beware of \n   rounding errors when comparing reals).\n")]).
:- comment((=\=) / 3, [summary : "Reified arithmetic comparison", see_also : [(=\=) / 2, $\= / 3], args : ["Expr1" : "An arithmetic expression", "Expr2" : "An arithmetic expression", "Bool" : "Variable, 0 or 1"], exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("    Reified version of =\\=/2, i.e. the truth value of the comparison is\n    reflected in the value of the 0/1 variable Bool.\n<P>\n    This constraint suspends until its first two arguments are ground.\n    It then unifies Bool according to the truth value of the corresponding\n    =\\=/2 constraint.\n")]).
:- comment((>) / 2, [summary : "The value of Expr1 is greater than the value of Expr2.", template : "?Expr1 > ?Expr2", see_also : [(>) / 3, _31103 : (>) / 2], args : ["Expr1" : "An arithmetic expression", "Expr2" : "An arithmetic expression"], fail_if : "   fails if the value of Expr1 is not greater than the value of Expr2", exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("   Suspends until both Expr1 and Expr2 are ground, and then both arguments\n   are evaluated and compared, succeeding iff Expr1 is greater than Expr2 \n   (beware of rounding errors when comparing reals).\n")]).
:- comment((>) / 3, [summary : "Reified arithmetic comparison", see_also : [(>) / 2, $> / 3], args : ["Expr1" : "An arithmetic expression", "Expr2" : "An arithmetic expression", "Bool" : "Variable, 0 or 1"], exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("    Reified version of >/2, i.e. the truth value of the comparison is\n    reflected in the value of the 0/1 variable Bool.\n<P>\n    This constraint suspends until its first two arguments are ground.\n    It then unifies Bool according to the truth value of the corresponding\n    >/2 constraint.\n")]).
:- comment((>=) / 2, [summary : "The value of Expr1 is greater than or equal to the value of Expr2.", template : "?Expr1 >= ?Expr2", see_also : [(>=) / 3, _30283 : (>=) / 2], args : ["Expr1" : "An arithmetic expression", "Expr2" : "An arithmetic expression"], fail_if : "   fails if the value of Expr1 is smaller than the value of Expr2", exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("   Suspends until both Expr1 and Expr2 are ground, and then both arguments\n   are evaluated and compared, succeeding iff Expr1 is greater than or equal to\n   Expr2 (beware of rounding errors when comparing reals).\n")]).
:- comment((>=) / 3, [summary : "Reified arithmetic comparison", see_also : [(>=) / 2, $>= / 3], args : ["Expr1" : "An arithmetic expression", "Expr2" : "An arithmetic expression", "Bool" : "Variable, 0 or 1"], exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("    Reified version of >=/2, i.e. the truth value of the comparison is\n    reflected in the value of the 0/1 variable Bool.\n<P>\n    This constraint suspends until its first two arguments are ground.\n    It then unifies Bool according to the truth value of the corresponding\n    >=/2 constraint.\n")]).
:- comment(and / 2, [summary : "Both Expr1 and Expr2 arithmetically evaluate to 1", template : "?Expr1 and ?Expr2", see_also : [and / 3, or / 2, => / 2, neg / 1, _43711 : and / 2], args : ["Expr1" : "A boolean expression", "Expr2" : "A boolean expression"], fail_if : "Expr1 or Expr2 do not both evaluate to 1", eg : "\n\t?- B and 1, B = 1.\n\tB = 1\n\tYes (0.00s cpu)\n\n\t?- B and 1, B = 0.\n\tNo (0.00s cpu)\n\n\t% arguments are typically reifiable expressions:\n\t?- X > 5 and X < 7, X = 7.\n\tNo (0.00s cpu)\n\n\t% the previous example is equivalent to:\n\t?- >(X,5,B1), <(X,7,B2), B1 and B2, X=7.\n\tNo (0.00s cpu)\n\n\t% and/or/=>/neg are themselves reifiable:\n\t?- X > 5 and neg(X < 7), X = 7.\n\tX = 7\n\tYes (0.00s cpu)\n\t", exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("    Suspends until both Expr1 and Expr2 are ground, and then both arguments\n    are evaluated. Succeeds if both evaluate to 1.\n<P>\n    Typically, the expressions contains reifiable constraints, in which case\n    a corresponding reified constraint is set up, and the expression is\n    replaced by the resulting boolean variable.\n")]).
:- comment(and / 3, [summary : "Reified boolean operation", see_also : [and / 2], args : ["Expr1" : "An arithmetic expression", "Expr2" : "An arithmetic expression", "Bool" : "Variable, 0 or 1"], exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("    Reified version of and/2, i.e. the truth value of the boolean operation\n    is reflected in the value of the 0/1 variable Bool.\n<P>\n    This constraint suspends until its first two arguments are ground.\n    It then unifies Bool according to the truth value of the corresponding\n    and/2 constraint.\n")]).
:- comment(integers / 1, [summary : "Constrain Vars to be integers", args : ["Vars" : "List of variables or integers"], see_also : [(::) / 2, #:: / 2, reals / 1], fail_if : "Vars contains non-integers.", desc : html("    This constraint suspends until its argument is ground. It then succeeds\n    iff Vars is an integer or a list of integers.")]).
:- comment(neg / 1, [summary : "Expr arithmetically evaluates to 0", template : "neg ?Expr", see_also : [neg / 2, and / 2, or / 2, => / 2, _45422 : neg / 1], args : ["Expr" : "A boolean expression"], fail_if : "Expr does not evaluate to 0", eg : "\n\t?- neg B, B = 1.\n\tNo (0.00s cpu)\n\n\t?- neg B, B = 0.\n\tB = 0\n\tYes (0.00s cpu)\n\n\t% arguments are typically reifiable expressions:\n\t?- neg X > 7, X = 8.\n\tNo (0.00s cpu)\n\n\t% the previous example is equivalent to:\n\t?- >(X,7,B), neg B, X=8.\n\tNo (0.00s cpu)\n\n\t% and/or/=>/neg are themselves reifiable:\n\t?- neg(X > 7 or X < 5), X = 7.\n\tX = 7\n\tYes (0.00s cpu)\n\t", exceptions : [24 : "Expr is not an arithmetic expression."], desc : html("    Suspends until Expr is ground, and then evaluates it. Succeeds if it\n    evaluates to 0.\n<P>\n    Typically, the expression contains reifiable constraints, in which case\n    a corresponding reified constraint is set up, and the expression is\n    replaced by the resulting boolean variable.\n")]).
:- comment(neg / 2, [summary : "Reified boolean operation", see_also : [neg / 1], args : ["Expr" : "An arithmetic expression", "Bool" : "Variable, 0 or 1"], exceptions : [24 : "Expr is not an arithmetic expression."], desc : html("    Reified version of neg/1, i.e. the truth value of the boolean operation\n    is reflected in the value of the 0/1 variable Bool.\n<P>\n    This constraint suspends until its first argument is ground.\n    It then unifies Bool according to the truth value of the corresponding\n    neg/1 constraint.\n")]).
:- comment(or / 2, [summary : "At least one of Expr1 or Expr2 arithmetically evaluate to 1", template : "?Expr1 or ?Expr2", see_also : [or / 3, and / 2, => / 2, neg / 1, _44269 : or / 2], args : ["Expr1" : "A boolean expression", "Expr2" : "A boolean expression"], fail_if : "Neither Expr1 nor Expr2 evaluates to 1", eg : "\n\t?- B or 1, B = 0.\n\tB = 0\n\tYes (0.00s cpu)\n\n\t?- B or 0, B = 0.\n\tNo (0.00s cpu)\n\n\t% arguments are typically reifiable expressions:\n\t?- X > 7 or X < 5, X = 7.\n\tNo (0.00s cpu)\n\n\t% the previous example is equivalent to:\n\t?- >(X,7,B1), <(X,5,B2), B1 or B2, X=7.\n\tNo (0.00s cpu)\n\n\t% and/or/=>/neg are themselves reifiable:\n\t?- X > 7 or neg(X < 5), X = 7.\n\tX = 7\n\tYes (0.00s cpu)\n\t", exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("    Suspends until both Expr1 and Expr2 are ground, and then both arguments\n    are evaluated. Succeeds if at least one evaluates to 1.\n<P>\n    Typically, the expressions contains reifiable constraints, in which case\n    a corresponding reified constraint is set up, and the expression is\n    replaced by the resulting boolean variable.\n")]).
:- comment(or / 3, [summary : "Reified boolean operation", see_also : [or / 2], args : ["Expr1" : "An arithmetic expression", "Expr2" : "An arithmetic expression", "Bool" : "Variable, 0 or 1"], exceptions : [24 : "Expr1 or Expr2 is not an arithmetic expression."], desc : html("    Reified version of or/2, i.e. the truth value of the boolean operation\n    is reflected in the value of the 0/1 variable Bool.\n<P>\n    This constraint suspends until its first two arguments are ground.\n    It then unifies Bool according to the truth value of the corresponding\n    or/2 constraint.\n")]).
:- comment(reals / 1, [summary : "Constrain Vars to be a number or list of numbers", args : ["Vars" : "List of variables or numbers"], see_also : [(::) / 2, $:: / 2, integers / 1], fail_if : "Vars contains non-numbers.", eg : "\n    ?- reals(L), L = [3.4, 7].\n    L = [3.4, 7]\n    Yes (0.00s cpu)\n\n    ", desc : html("    This constraint suspends until its argument is ground. It then succeeds\n    iff Vars is a number or a list of numbers (any type).")]).
:- comment(neg_body / 3, hidden).
:- comment('=>_body' / 4, hidden).
:- comment(or_body / 4, hidden).
:- comment(and_body / 4, hidden).
:- comment('>_body' / 4, hidden).
:- comment('<_body' / 4, hidden).
:- comment('>=_body' / 4, hidden).
:- comment('=<_body' / 4, hidden).
:- comment('=\\=_body' / 4, hidden).
:- comment('=:=_body' / 4, hidden).
:- comment('$>_body' / 4, hidden).
:- comment('$<_body' / 4, hidden).
:- comment('$>=_body' / 4, hidden).
:- comment('$=<_body' / 4, hidden).
:- comment('$\\=_body' / 4, hidden).
:- comment('$=_body' / 4, hidden).
:- comment('#>_body' / 4, hidden).
:- comment('#<_body' / 4, hidden).
:- comment('#>=_body' / 4, hidden).
:- comment('#=<_body' / 4, hidden).
:- comment('#\\=_body' / 4, hidden).
:- comment('#=_body' / 4, hidden).
:- comment('#::_body' / 4, hidden).
:- comment('$::_body' / 4, hidden).
:- comment('::_body' / 4, hidden).
:- comment(neg_body / 2, hidden).
:- comment('=>_body' / 3, hidden).
:- comment(or_body / 3, hidden).
:- comment(and_body / 3, hidden).
:- comment('>_body' / 3, hidden).
:- comment('<_body' / 3, hidden).
:- comment('>=_body' / 3, hidden).
:- comment('=<_body' / 3, hidden).
:- comment('=\\=_body' / 3, hidden).
:- comment('=:=_body' / 3, hidden).
:- comment('$>_body' / 3, hidden).
:- comment('$<_body' / 3, hidden).
:- comment('$>=_body' / 3, hidden).
:- comment('$=<_body' / 3, hidden).
:- comment('$\\=_body' / 3, hidden).
:- comment('$=_body' / 3, hidden).
:- comment('#>_body' / 3, hidden).
:- comment('#<_body' / 3, hidden).
:- comment('#>=_body' / 3, hidden).
:- comment('#=<_body' / 3, hidden).
:- comment('#\\=_body' / 3, hidden).
:- comment('#=_body' / 3, hidden).
:- comment('#::_body' / 3, hidden).
:- comment('$::_body' / 3, hidden).
:- comment('::_body' / 3, hidden).
